#!/usr/bin/env python

import wx
from core.ide.themesmanager import ThemesManager
from core.utils.druidtip import DruidTip
class AutoCompletion():
    def __init__(self,parent,pos,wysiwing):
        self._parent=parent
        self._pos=pos
        self.wysiwing=wysiwing
        self._displayList=[]
        self._word=""
        self.frame = wx.Frame(self._parent,-1, pos = self._pos, size = (150, 250), style = wx.STAY_ON_TOP | wx.BORDER_NONE)
		#self.frame=wx.PopupWindow(self._parent)
        #self.frame.SetSize((150, 250))
        #self.frame.SetPosition(self._pos)
        self.list = wx.ListCtrl( self.frame, -1, size = (150, 250), style = wx.LC_REPORT | wx.BORDER_SIMPLE | wx.HSCROLL)
        self.list.SetImageList(ThemesManager().getDefaultTheme().getWxLib("script_16"), wx.IMAGE_LIST_SMALL)
        self.list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onItemSelected, self.list)
        self.frame.Show(False)
        self.tip=DruidTip(self.frame)
        self.setTypeFilter()
        
        
    def setTypeFilter(self,typeFilter=[]):
        
        self.typeFilter=typeFilter 
        
    def onItemSelected(self,e):
        self._current=e.m_itemIndex
        try:
            self.showDoc(self._current)
        except:
            pass
    
    def showDoc(self,item):
        id_=len(self._displayList)-1-item
        if type(self._displayList[id_])==tuple:
            ctx=self._displayList[id_][1]
        else:
            ctx=self._displayList[id_]

        if hasattr(ctx, "doc") and ctx.doc:
            self.tip.setText(ctx.doc)
            r=self.list.GetItemRect(item)
            p=self.list.GetScreenPosition()
            s=self.list.GetSize()
            self.tip.SetPosition((s[0]+p[0],r.GetTop()+p[1]))
            self.tip.Show(True)
        else:
            self.tip.Show(False) 


    def setList(self,wordList,wordType):
        self._wordList = wordList
        self._displayList = wordList
     
    def getWord(self):
        return self.list.GetItem(self._current, 0).GetText()

    def setWord(self,word):
        if not word or self._word==word:
            word = "";
        result = []
        hightValue = False
        self._word=word
        if not word:
            self._displayList = self._wordList
            self.draw()
            return 
        for ctx in self._wordList:
            if self._wordList[0]=="_" and word[0]!="_":
                continue
            
            if self.typeFilter:
                try:
                    self.typeFilter.index(ctx.type)
                except:
                    continue
            
            keyword=ctx.name
            word1 = word.lower()
            heuristic = 0
            #default
            if keyword == word:
                heuristic += 150
            if keyword.find(word) == 0:
                heuristic += 100
            elif keyword.find(word) > 0:
                    heuristic += 50;
            #heuristic*=10
            #lower
            keyword1=keyword.lower()

            if keyword1 == word1:
                heuristic += 149
            if keyword1.find(word1)==0:
                heuristic += 99
            elif keyword1.find(word1)>0:
                heuristic += 49;
                      
            heuristic *= 10
            if heuristic == 0 and hightValue:
                continue
            #aproximation
            if heuristic == 0:
                prev =- 1
                for char in word1:
                    pos=keyword1.find(char)
                    if pos>-1:
                        word1=word1[:pos] + "$" + word1[pos+1:]
                        heuristic += 3
                        if prev >- 1 and pos - 1 == prev:
                            heuristic += 7
                        prev=pos
            heuristic-=len(keyword1)-len(word1)
            if heuristic > 80:
                hightValue = True
            
            if heuristic and (heuristic > 80 or not hightValue):
                result.append((heuristic,ctx))
                
        
        result.sort()
        #while len(result) and result[0][0] >= 10000-80:
        #    result=result[1:]
        self._displayList=result
        self.draw()
    
    def validate(self):
        item = self._current
        word=self.list.GetItem(item, 0).GetText()
        self.wysiwing.insertWord(word,True)
    
    def draw(self):
        self.list.DeleteAllItems()
        item=None
        for ctx in self._displayList:
            
            if type(ctx)==tuple:
                ctx=ctx[1]
            if ctx.name[0]=="_" and self._word and self._word[0]!="_":
                continue
            imageId=0
            if ctx.type=="class":
                imageId=ThemesManager().getDefaultTheme().getWxIdImage("script_16","class")
            elif ctx.type=="method" or ctx.type=="function":
                imageId=ThemesManager().getDefaultTheme().getWxIdImage("script_16","method")
            elif ctx.type=="property":
                imageId=ThemesManager().getDefaultTheme().getWxIdImage("script_16","property")
            elif ctx.type=="module":
                imageId=ThemesManager().getDefaultTheme().getWxIdImage("script_16","module")
            elif ctx.type=="var":
                imageId=ThemesManager().getDefaultTheme().getWxIdImage("script_16","local")
            #elif ctx.pyTypeValue:
                
            if not item:
                item=self.list.InsertImageStringItem(0,ctx.name,imageId)
            else:
                self.list.InsertImageStringItem(0,ctx.name,imageId)
                #InsertImageStringItem
        
        #self.list.SetHelpText("This is my very own help message!")
        self.list.SetColumnWidth(0, self.list.GetClientSize()[0])
        self.list.Select(0)
        self._current=0
        self.showDoc(0)
        
    
    def onActivated(self,e):
        word=self.list.GetItem(e.m_itemIndex, 0).GetText()
        self.wysiwing.insertWord(word,True)
        #e.Skip()
    
    def onKeyDown(self,e):
        key = e.GetKeyCode()
        if key == 315 or key == 317:
            e.Skip()
        elif self.wysiwing:
            self.wysiwing.insertKeyEvent(e)
        #self.list.SetFocus()
        #self.setWord(self._word)
        #self.wysiwing.SetFocus()
        #e.Skip()
    
    def goDown(self):
        if self._current<len(self._displayList):
            #self.list.SetFocus()
            self.list.Select(self._current,0)
            self._current+=1
            self.list.Select(self._current)
    
    def goUp(self):
        if self._current > 0:
            #self.list.SetFocus()
            self.list.Select(self._current,0)
            self._current-=1
            self.list.Select(self._current)
    
    def onSelect(self,e):
        self.list.SetItemBackgroundColour(self._current,wx.BLUE)
        self._current=e.m_itemIndex
        self.wysiwing.SetFocus()
        e.Skip()
    
    def open(self):
        
        
        #self.SetImageList(ThemesManager().getDefaultTheme().getWxLib("icone_16"))
        self.frame.Show(True)
        self.list.InsertColumn(0, "Completion")
        self.draw()
        self.list.SetColumnWidth(0, self.list.GetClientSize()[0])
        self.list.SetFocus()
        #self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
        #self.list.Raise()
        #self.list.Refresh()
        #self.list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelect)
        #self.list.Bind(wx.EVT_KEY_DOWN, self.onKeyDown)
        self.list.Bind(wx.EVT_CHAR, self.onKeyDown)
        self.list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.onActivated)
        #self.list.Bind(wx.EVT_LEFT_UP,self.onSelect)
        #self.list.Bind(wx.EVT_LIST_ITEM_SELECTED,self.onSelect)
        
        
    def destroy(self):
        #self.frame.Destroy()
        #self.list.Destroy()
        self.frame.Show(False)
        self.tip.Show(False)
        self.tip.Destroy()
        self.tip=None
        self.wysiwing=None
        self.frame=None
        self.list=None
        
        
def customsort(a,b):
    if a[0]<b[0]:
        return -1
    elif a[0]>b[0]:
        return 1
    else:
        if a[1].name.lower()<b[1].name.lower():
            return -1
        elif a[1].name.lower()<b[1].name.lower():
            return 1
        else:
            return 0
        